package com.hwtx.form.domain.def;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.databind.JsonNode;
import com.hwtx.form.domain.FormConstants;
import com.hwtx.form.dto.FormProDto;
import com.hwtx.form.util.BeanUtil;
import com.hwtx.form.util.FormUtil;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Objects;

import static com.hwtx.form.domain.FormConstants.AUTH_KEY;
import static com.hwtx.form.util.FormUtil.replaceUrl;
import static com.hwtx.form.util.JacksonUtil.readJson;


@EqualsAndHashCode(callSuper = true)
@Slf4j
public class FormDef extends FormProperties {

    @Getter
    @JsonIgnore
    private FormValidateDef formValidateDef;
    @JsonIgnore
    private JsonNode rawRoot;
    @Getter
    private boolean auth;


    private FormDef() {
    }

    public static FormDef of(String content, FormProperties formProperties) {
        FormDef formDef = new FormDef();
        BeanUtil.copyFieldValue(formDef, formProperties);
        handleFormProperties(formDef, content, formProperties.getClassify());
        return formDef;
    }

    public static FormDef of(String name, String content, Long formId, String type, int classify) {
        FormDef formDef = new FormDef();
        formDef.setFormId(formId);
        formDef.setType(type);
        formDef.setName(name);
        handleFormProperties(formDef, content, classify);
        return formDef;
    }

    private static void handleFormProperties(FormDef formDef, String content, int classify) {
        formDef.formValidateDef = buildValidateDef(content, formDef, classify);
        formDef.rawRoot = readJson(content);
        if (formDef.rawRoot != null) {
            formDef.auth = CollectionUtils.isNotEmpty(formDef.rawRoot.findValues(AUTH_KEY));
        }
        formDef.setMeta(FormUtil.getMeta(content, formDef.getName()));

    }

    private static FormValidateDef buildValidateDef(String content, FormDef formDef, int classify) {
        FormValidateDef formValidateDef = new FormValidateDef();
        if (Objects.equals(classify, FormConstants.FORM_CLASSIFY_FORM)) {
            formValidateDef.buildFormValidateItem(content);
            formValidateDef.buildCustomerValidations(formDef);
        }
        return formValidateDef;
    }

    public JsonNode getJsonRoot() {
        return rawRoot.deepCopy();
    }

    public FormValidateDef.ValidationResult validateForm(String name, Object value) {
        return formValidateDef.validateForm(this, name, value);
    }

    public String updateFormContent(String content, FormProDto formProDto) {
        String domain = formProDto.getDomain();
        if (StringUtils.isNotEmpty(domain)) {
            content = updateDomain(content, domain, formProDto.getFormName());
        }
        return content;
    }

    private String updateDomain(String content, String domain, String formName) {
        JsonNode rootNode = readJson(content);
        if (rootNode != null) {
            FormConstants.ALL_API.forEach(key -> replaceUrl(rootNode, key.getName(), domain, formName));
            return rootNode.toPrettyString();
        }
        throw new RuntimeException("表单内容解析失败");
    }
}